#include "jsnix.h"
#include <signal.h>
#include <semaphore.h>
#include <mqueue.h>

static int _os_sleep(JSCTX * ctx){
        unsigned int secs = __get_number_value(ctx, 0);

        unsigned int rc = sleep(secs);
	__put_int_value(ctx, rc);

       return 1;
}

static int _os_usleep(JSCTX *ctx){
        unsigned int usecs = __get_number_value(ctx, 0);
        __put_int_value(ctx, usleep(usecs));

	return 1;
}

static int _os_getuid(JSCTX *ctx)
{
	__put_number_value(ctx, getuid());
	return 1;
}
static int _os_geteuid(JSCTX *ctx)
{
	__put_number_value(ctx, geteuid());
	return 1;
}
static int _os_getgid(JSCTX *ctx)
{
	__put_number_value(ctx, getgid());
	return 1;
}
static int _os_getegid(JSCTX *ctx)
{
	__put_number_value(ctx, getegid());
	return 1;
}

static int _os_getpid(JSCTX *ctx)
{
	__put_number_value(ctx, getpid());
	return 1;
}
static int _os_setsid(JSCTX *ctx)
{
	__put_number_value(ctx, setsid());
	return 1;
}
static int _os_fork(JSCTX *ctx)
{
	__put_number_value(ctx, fork());
	return 1;
}

static int _os_exit(JSCTX *ctx)
{
	int status = __get_int_value(ctx, 0);
	exit(status);

	return 0;
}
static int _os_wait(JSCTX *ctx)
{
	int status;
	pid_t pid = wait(&status);
        int oid = __start_object(ctx);
	__put_int_prop(ctx, oid, "pid", pid);
	__put_int_prop(ctx, oid, "status", status);

	return 1;
}
static int _os_pause(JSCTX *ctx)
{
	__put_number_value(ctx, pause());
	return 1;
}

static int _os_exec(JSCTX *ctx)
{
	int cnt = __count(ctx);
	if(cnt < 1){
		__put_number_value(ctx, -1);
		return 1;
	}
	char *args[11];
	const char *file = __get_string_value(ctx, 0);
	int i;
	if(cnt>10)
		cnt = 10;
	for(i=0; i<cnt; i++)
		args[i] = __get_string_value(ctx, i);
	args[i] = NULL;
	__put_int_value(ctx, execvp(file, args));

	return 1;
}


static int _os_getenv(JSCTX *ctx)
{
	const char *name = __get_string_value(ctx, 0);
	__put_string_value(ctx, getenv(name));
	return 1;
}

static int _os_setenv(JSCTX *ctx)
{
	const char *name = __get_string_value(ctx, 0);
	const char *value = __get_string_value(ctx, 1);

	__put_int_value(ctx, setenv(name, value, 1));

	return 1;
}

static int _os_unsetenv(JSCTX *ctx)
{
	const char * name = __get_string_value(ctx, 0);
	__put_int_value(ctx, unsetenv(name));

	return 1;
}


int load_process_module(JSCTX *ctx){
	__start_global_object(ctx, "process");
	__register_function(ctx, "sleep", _os_sleep, 1);
	__register_function(ctx, "usleep", _os_usleep, 1);
	__register_function(ctx, "getuid", _os_getuid, 0);
	__register_function(ctx, "geteuid", _os_geteuid, 0);
	__register_function(ctx, "getgid", _os_getgid, 0);
	__register_function(ctx, "getegid", _os_getegid, 0);
	__register_function(ctx, "getpid", _os_getpid, 0);
	__register_function(ctx, "setsid", _os_setsid, 0);
	__register_function(ctx, "fork", _os_fork, 0);
	__register_function(ctx, "exec", _os_exec, __VARARGS);
	__register_function(ctx, "exit", _os_exit, 1);
	__register_function(ctx, "wait", _os_wait, 0);
	__register_function(ctx, "pause", _os_pause, 1);
	__register_function(ctx, "getenv", _os_getenv, 1);
	__register_function(ctx, "setenv", _os_setenv, 2);
	__register_function(ctx, "unsetenv", _os_unsetenv, 1);

	__end_object(ctx)

	return 0;
}

